package com.project.easy.common.framework.web.service.impl.captcha;

import com.google.code.kaptcha.util.Config;
import com.project.easy.common.framework.captcha.core.CaptchaProcessor;
import com.project.easy.common.framework.captcha.core.DefaultKaptchaProduct;
import com.project.easy.common.framework.captcha.core.IPersistenceCaptcha;
import com.project.easy.common.framework.captcha.core.vo.BaseCaptchaConfigVo;
import com.project.easy.common.framework.captcha.core.vo.CaptchResultVo;
import  com.project.easy.common.util.string.StringUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.Objects;
import java.util.Properties;

/**
 * @author GreatorMan.cool
 * @copyright: Copyright (c) 2020
 * @company: 扬起科技有限公司
 * @date 2021/11/23 22:27
 * @description:默认简单验证实现
 */
public abstract class SimpleCaptchaProcessor extends CaptchaProcessor implements  InitializingBean, IPersistenceCaptcha {
    /**
     * 图片生产者
     */
    private DefaultKaptchaProduct baseKaptcha;
    /**
     * 配置
     */
    @Autowired
    private BaseCaptchaConfigVo baseCaptchaConfigVo;
    /**
     * 验证编码生产者
     *
     * @return 返回生产图
     */
    @Override
    public DefaultKaptchaProduct getProducter() {
        return  baseKaptcha;
    }
    /**
     * 返回配置
     *
     * @return
     */
    @Override
    public BaseCaptchaConfigVo getConfig() {
        return baseCaptchaConfigVo;
    }

    /**
     * 验证编码持久化
     *
     * @param captchResultVo
     * @return true 持久化成功 false 失败
     */
    @Override
    public Boolean persistence(CaptchResultVo captchResultVo) {
        if (captchResultVo.getHasSuccess()) {
            return this.save(captchResultVo);
        }
        return Boolean.FALSE;
    }
    /**
     * Invoked by the containing {@code BeanFactory} after it has set all bean properties
     * and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
     * <p>This method allows the bean instance to perform validation of its overall
     * configuration and final initialization when all bean properties have been set.
     *
     * @throws Exception in the listener of misconfiguration (such as failure to set an
     *                   essential property) or if initialization fails for any other reason
     */
    @Override
    public void afterPropertiesSet() throws Exception {
        Properties properties = new Properties();
        properties.put("kaptcha.border", this.getConfig().getHasBorder());
        properties.put("kaptcha.textproducer.font.color", this.getConfig().getFontColor());
        properties.put("kaptcha.textproducer.char.length", this.getConfig().getLength());
        properties.put("kaptcha.textproducer.char.width", this.getConfig().getWidth());
        properties.put("kaptcha.image.height", this.getConfig().getHeight());
        properties.put("kaptcha.textproducer.font.size", this.getConfig().getFontSize());
        Config config = new Config(properties);
        DefaultKaptchaProduct defaultKaptcha = new DefaultKaptchaProduct();
        defaultKaptcha.setConfig(config);
        this.baseKaptcha = defaultKaptcha;
    }

    /**
     * 验证编码实现
     * @param captchaKey 编码
     * @param text       内容
     * @return true 成功 false 失败
     */
    @Override
    public Boolean validata(String captchaKey, String text) {
        if (StringUtil.isBlank(captchaKey) || StringUtil.isBlank(text)) {
            return Boolean.FALSE;
        }
        CaptchResultVo captchResultVo = this.query(captchaKey);
        if (Objects.isNull(captchResultVo)) {
            return Boolean.FALSE;
        }
        if (Objects.isNull(captchResultVo.getExpireTime())) {
            return Boolean.FALSE;
        }
        if (!Objects.isNull(captchResultVo.getHasDel()) && captchResultVo.getHasDel()) {
            return Boolean.FALSE;
        }
        if (captchResultVo.getExpireTime().after(new Date())) {
            return Boolean.FALSE;
        }
        if (text.equalsIgnoreCase(captchResultVo.getResult())) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
}
